package aqsframework.selfmutex;

/**
 * 使用aqs自定义一个同步器：互斥锁
 */
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;

public class Mutex implements Lock {

    //
    Sync sync = new Sync();

    /**
     * 独占式抢占锁
     */
    @Override
    public void lock() {
        sync.acquire(1);
    }

    /**
     * 共享式抢占锁
     */
    @Override
    public boolean tryLock() {
        return sync.tryAcquire(1);
    }

    @Override
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }



    @Override
    public boolean tryLock(long time, TimeUnit unit) {
        return false;
    }


    @Override
    public void unlock() {
        sync.release(1);
    }

    @Override
    public Condition newCondition() {
        return sync.new ConditionObject();
    }

    private static class Sync extends AbstractQueuedSynchronizer {

        //判断线程是否占用锁
        @Override
        protected boolean isHeldExclusively() {
            return 1 == getState();
        }

        @Override
        protected boolean tryAcquire(int arg) {
            if(compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }else {
                return false;
            }
        }

        @Override
        protected boolean tryRelease(int arg) {
            if (getState() == 1) {
                throw new IllegalMonitorStateException();
            }
            setState(0);
            setExclusiveOwnerThread(null);
            return true;
        }
    }


}

